#ifndef _USERFACESAMPLE_H_
#define _USERFACESAMPLE_H_
#include <stdint.h>
#include <stdbool.h>
#include <aos/kernel.h>
#include <if_v.h>

/************************   该区间为用户自行设置区域   **************************/
#define SIDE_FACE_ANGLE_MIN     5      //侧脸的最小绝对值角度
#define SIDE_FACE_ANGLE_MAX     60      //侧脸的最大绝对值角度
#define FRONTAL_FACE_ANGLE      10      //正脸的绝对值角度范围

#define FACE_POSITION_BOUNDARY_HORIZONTAL   (0.2f)      //人脸xmin需要在x方向(value)%右侧，xmax需在x方向(1-value)%左侧
#define FACE_POSITION_BOUNDARY_VERTICAL     (0.1f)      //人脸ymin需要在y方向(value)%下方，ymax需在y方向(1-value)%上方
#define FACE_POSITION_BOUNDARY_FAR          (0.17f)     //人脸(xmax-xmin)需要大于(value)%
#define FACE_POSITION_BOUNDARY_CLOSE        (0.45f)     //人脸(xmax-xmin)需要小于(value)%

//多角度注册需要注册的各个角度，如果需要增删的话请调整enum
//该枚举需从0开始，最大角度个数为USER_MULTI_ANGLE_NUM
enum{
    USER_FACE_CHECK_LEFT = 0,	     /*  left   */
    USER_FACE_CHECK_RIGHT,           /*  right  */
    USER_FACE_CHECK_UP,              /*  up     */
    USER_FACE_CHECK_DOWN,            /*  down   */
    USER_FACE_CHECK_MIDDLE,          /*  middle */
	USER_MULTI_ANGLE_NUM              /*  max 多角度注册的需要注册角度的个数*/
};
/************************    用户自行设置区域结束   ***************************/

#define USER_MULTI_ANGLE_NUM 5
#define USER_FACE_NAME_MAX_NUM  32
#define USER_FACE_FEATURE_MAX_NUM	(FACE_FEATURE_MAX_NUM / USER_MULTI_ANGLE_NUM)
#define USER_FACE_FEATURE_SIZE	(sizeof(user_face_manage_sample_t))

/*********************   用户二次管理结构体sample   *****************/
/*Instruction:用户二次管理的二次管理信息的最小单元，sample中只有userId（用户id）及multiAngleIdMap[USER_MULTI_ANGLE_NUM]（用户id映射的底层人脸特征id）。
 *			  用户可以自行增加需要增加的信息，比如id姓名、权限、注册时间等等.
 */

typedef struct user_face_manage_sample{
	uint16_t userId;
	uint8_t  userName[USER_FACE_NAME_MAX_NUM];
	uint8_t  admin; 
	uint16_t multiAngleIdMap[USER_MULTI_ANGLE_NUM];
}user_face_manage_sample_t;
/******************************************************************/

/*********************  多角度注册结构体sample   *****************/
typedef struct user_face_algo_sample{
	uint8_t processRunFlag;					//多角度常驻线程正在进行多角度检测的标志位
	uint8_t processStopFlag;				//多角度检测的中止运行标志位
	uint8_t firstRegisterFlag;
	uint8_t coverRegisterFlag;
	uint8_t admin;	
	uint16_t usrID;						//管理员权限
	uint8_t userName[USER_FACE_NAME_MAX_NUM]; //用户名
	uint8_t multiAngle;						//本次检测的角度类型
	uint8_t multiAngleReady;	            //已注册OK的角度
	int timeout;							//超时时间（s），0为永不超时
	long long recordTime;					//记录当前时间，用于超时判断		
	aos_mutex_t mutex;						//锁
}user_face_algo_sample_t;
/******************************************************************/


// void multi_angle_reg_run(void);
// int multi_angle_result_send_user_sample(int result, int multAngle, TsmFaceResult *faceResult);
// int user_face_manage_ff_num(void);
// void user_face_manage_ff_list(uint32_t *list);

/*
-------------------------------------------------------------------
----------------------------多角度注册------------------------------
-------------------------------------------------------------------
*/
/*
Interface Explain:通知算法进行多角度检测
Instruction:
input: 
return:
*/
void multi_angle_reg_run(void);

/*
Interface Explain:返回全局变量g_userFaceAlgoSample的地址
Instruction:
input: 
return: 全局变量g_userFaceAlgoSample的地址
*/
user_face_algo_sample_t *get_user_facec_algo_sample_info(void);

/*
Interface Explain:返回全局变量g_userFaceManageSample的地址
Instruction:
input: 
return: 全局变量g_userFaceManageSample的地址
*/
user_face_manage_sample_t *get_user_facec_manage_sample_info(void);

/*
Interface Explain:初始化用户二次管理及多角度注册的相关数据
Instruction:如果要使用相应功能，请在开机后执行该函数，目前SDK中放在常驻线
user_face_algo_sample_process中运行,供参考。
input: 
return: 0	成功
	    !0  失败
*/
int user_face_initial_sample(void);

/*
Interface Explain:清空用户二次管理及多角度注册的缓存数据
Instruction:在执行完或打断一次多角度注册后需要调用该接口将缓存数据清空，目前
SDK中放在常驻线程user_face_algo_sample_process中运行,供参考。
input: 
return: 
*/
int user_face_initial_sample(void);

/*
Interface Explain:清空用户二次管理及多角度注册的缓存数据
Instruction:在执行完或打断一次多角度注册后需要调用该接口将缓存数据清空，目前
SDK中放在常驻线程user_face_algo_sample_process中运行,供参考。
input: 
return: 
*/
void user_face_process_clear_sample(void);

/*
Interface Explain:触发user_face_algo_sample_process运行的接口函数
Instruction:该函数为用户触发多角度注册的接口函数。接收到用户发送的信息后，调用该接口即可。当前SDK中在cli中实现示例（命令:ifv reg_mult x  [其中x为超时时间，单位为秒]，供参考。
input: 	multiAngle：本次进行的角度
		timeout：超时时间,单位秒。0表示永不超时

return: 0	成功
		!0  失败
*/
int user_multi_angle_reg_sample_run(uint8_t admin, uint8_t *userName, uint8_t multiAngle, uint8_t timeout, uint16_t usrID);

/*
Interface Explain:用户二次管理及多角度注册的常驻线程
Instruction:该函数为用户二次管理及多角度注册的的主要函数。平时处于等待状态，接到用户的注册命令时，用于多角度注册、识别功能的触发，同时判断用户是否进行打断、超时，并对其进行对应的异常处理。当前SDK中开机运行,供参考。
input: 
return: 
*/
void user_face_algo_sample_process(void);

/*
Interface Explain:对算法“注册”结果，进行多角度注册判断的接口函数
Instruction:该函数用于对算法“注册”结果进行判断，应该放在user_multi_angle_result_check_sample函数中。判断是否满足各个角度，如果满足某一角度，调整全局变量的参数，通知user_face_algo_sample_process进行下一个角度的注册，如果全部角度都满足，则进行用户id的二次管理，调用user_face_manage_ff_add新增用户id，并将底层人脸特征id和用户id建立起映射关系。
input: pData : 算法回调的数据
return: 0	成功
*/
int user_multi_angle_reg_result_check_sample(void *pData);

/*
Interface Explain:对算法“识别”结果，进行用户ID二次管理判断，并返回户ID的接口函数
Instruction:该函数用于对算法“识别”结果进行判断，应该放在user_multi_angle_result_check_sample函数中。查找底层人脸特征id和用户id的映射关系，返回用户id。
input: pData : 算法回调的数据
return: >0	 用户id
*/
int user_multi_angle_recog_result_check_sample(void *pData);

/*
Interface Explain:对算法“注册”“识别”结果，进行判断处理
Instruction:该函数用于对算法“识别”结果进行判断，应该放在算法的回调函数中。当前SDK中在userCmdRecogDoubleIRCb()里执行，供参考。
input: pData : 算法回调的数据
return: 
*/
void user_multi_angle_result_check_sample(void *pData);

/*
Interface Explain:打断多角度注册的接口函数
Instruction:用户需要打断多角度注册时，调用该接口即可。
input:
return:
*/
int user_multi_angle_reg_stop(void);


/*
-------------------------------------------------------------------
---------------------------用户ID管理-------------------------------
-------------------------------------------------------------------
*/

/*
Interface Explain:新增用户的二次管理id
Instruction:该接口请勿单独使用，请结合user_multi_angle_reg_result_check_sample使用，SDK中实现供参考。
input:
return:  成功 返回用户id
失败 <0
*/
int user_face_manage_ff_add(uint16_t usr_id);

/*
Interface Explain:删除指定用户的二次管理id
Instruction:删除指定用户的二次管理id，SDK中实现供参考。
input:	  需要删除的用户id
return:  成功 0
失败 <0
*/
int user_face_manage_ff_delete(uint32_t id);

/*
Interface Explain:清空用户全部二次管理id
Instruction:清空用户全部二次管理id，SDK中实现供参考。
input:	  
return:  成功 0
失败 <0
*/
int user_face_manage_ff_clear(void);

/*
Interface Explain:从非易失性存储中加载用户的二次管理信息
Instruction:从非易失性存储中加载用户的二次管理信息，SDK中实现供参考。
input:	  
return:  成功 0
失败 !0
*/
int user_face_manage_ff_load(void);

/*
Interface Explain:获取指定用户id的二次管理信息到feature中
Instruction:获取指定用户id的二次管理信息，获取到的数据为user_face_manage_sample结构体。SDK中实现供参考。
input:	  
return:  
*/
int user_face_manage_ff_get(uint32_t id, void *feature);

/*
Interface Explain:获取已注册id数量
Instruction:获取已注册用户id的数量，SDK中实现供参考。
input:	  
return: 已注册id数量
*/
int user_face_manage_ff_num(void);

/*
Interface Explain:获取已注册id列表到list中
Instruction:获取已注册id列表到list中。SDK中实现供参考。
input: list:存放已注册id的指针	  
return:  
*/
void user_face_manage_ff_list(uint16_t *list);

////////////////////////////////////////////////////////////以下内容为辅助实现，用户不必关心////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////以下内容为辅助实现，用户不必关心////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////以下内容为辅助实现，用户不必关心////////////////////////////////////////////////////////////
int user_ff_dump_id(void);
#endif
